package net.bcxuexi.pool;

import java.util.ArrayList;
import java.util.List;

import net.bcxuexi.tools.MyLog;


/**
 * 线程池，支持阻塞和飞阻塞方式调用
 * 
 * @author 毛伟
 */
public class WorkThreadPool {
	private List<PoolWorker> threads;
	private int maximumPoolSize;// 最大线程数
	private int corePoolSize;// 相当于最小线程数
	// 如果没有可用的线程，上锁即调用wait方法
	// 如果有可用的线程，解锁
	private Object lock = new Object();

	public WorkThreadPool(int corePoolSize, int maximumPoolSize) {
		this.corePoolSize = corePoolSize;
		this.maximumPoolSize = maximumPoolSize;
		// 初始化线程
		threads = new ArrayList<WorkThreadPool.PoolWorker>(maximumPoolSize);
		for (int i = 0; i < corePoolSize; i++) {
			PoolWorker pw = new PoolWorker();
			threads.add(pw);
			pw.start();
		}
	}

	/**
	 * 线程池能否在接受任务
	 */
	public boolean isFull() {
		if (threads.size() == maximumPoolSize) {
			for (PoolWorker thread : threads) {
				if (thread.isIdle())
					return true;
			}
		}
		return false;
	}

	/**
	 * 结束所有活动线程
	 */
	public void stop() {
		for (PoolWorker thread : threads) {
			thread.stopThread();
		}
	}

	/**
	 * 阻塞方式执行任务 如果没有多余的线程执行任务，则阻塞直到有多余线程
	 * 
	 * @throws InterruptedException
	 */
	public synchronized void executeBlock(Runnable r)
			throws InterruptedException {
		while (true) {
			boolean idle = false;
			PoolWorker thread = null;
			// 从已有的线程中找空闲线程
			for (PoolWorker t : threads) {
				if (t.isIdle()) {
					thread = t;
					break;
				}
			}
			if (thread == null) {// 如果没有找到空闲线程
				if (threads.size() < maximumPoolSize) {// 创建一个线程
					thread = new PoolWorker();
					threads.add(thread);
				}
			}
			if (thread == null) {
				idle = false;
			} else {
				boolean re = thread.execute(r);
				if (re) {
					idle = true;
				}
			}
			synchronized (lock) {
				if (!idle) {// 没有空闲线程
					lock.wait();
				} else {
					return;
				}
			}
		}
	}

	/**
	 * 执行任务
	 * 
	 * @return true:提交成功;false:没有多余的空闲线程执行任务
	 */
	public synchronized boolean execute(Runnable r) {
		PoolWorker thread = null;
		// 从已有的线程中找空闲线程
		for (PoolWorker t : threads) {
			if (t.isIdle()) {
				thread = t;
				break;
			}
		}
		if (thread == null) {// 如果没有找到空闲线程
			if (threads.size() < maximumPoolSize) {// 创建一个线程
				thread = new PoolWorker();
				threads.add(thread);
			} else {
				return false;
			}
		}
		boolean re = thread.execute(r);
		if (re) {
			return true;
		} else {
			MyLog.info("未找到空闲线程执行任务");
			return false;
		}
	}

	private class PoolWorker extends Thread {
		int status = 0;// 0:已停止;1:在运行;
		private boolean stopThread = false;
		private Runnable preTask;// 上一个任务
		private Runnable task;

		public void run() {
			stopThread = false;
			status = 1;
			long taskTime = System.currentTimeMillis();
			long currentTime = taskTime;
			while (!stopThread) {
				if (task != null && task != preTask) {
					task.run();
					preTask = task;
					taskTime = System.currentTimeMillis();
				}
				try {
					sleep(500);
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (RuntimeException e) {
					e.printStackTrace();
				}
				// 判断是否有新任务，没有释放锁lock
				synchronized (lock) {
					if (task == preTask) {
						lock.notifyAll();
					}
				}

				// 如果1分钟没有任务，将尝试结束线程
				currentTime = System.currentTimeMillis();
				if ((currentTime - taskTime > 60 * 1000) && task == preTask) {

					if (threads.size() > maximumPoolSize) {
						threads.remove(this);
						stopThread();
					}
				}

			}
			status = 0;
		}

		public synchronized boolean execute(Runnable task) {
			if (status == 0) {// 运行线程并执行任务
				this.task = task;
				status = 1;
				try {
					start();
				} catch (Exception ex) {
					MyLog.info(ex.getMessage());
					return false;
				}
				return true;
			} else if (status == 1) {// 在运行
				if (this.task != null && this.task != preTask) {// 有任务
					return false;
				} else {
					this.task = task;
					return true;
				}
			}
			return false;
		}

		/**
		 * @return true:没有任务，false:有任务
		 */
		public boolean isIdle() {
			if (task != null && task != preTask) {
				return false;
			}
			return true;
		}

		public void stopThread() {
			stopThread = true;
		}
	}
}
